package org.community.detail.service.common.update;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.community.detail.service.common.converter.JSONConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * 更新会话信息
 * 用户的头像昵称都是缓存在redis里的，在更新数据库的同时要更新到会话中，信息才能实时显示给用户
 */
@Service
@Transactional(
        isolation = Isolation.REPEATABLE_READ
)
@Slf4j
public class RedisUpgrade implements Update{

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private JSONConverter jsonConverter;

    @Value("${service.redis.duration}")
    private long expireTime;

    @Override
    public void update(Integer userId,String key, Object value) {
        log.info("update方法开始执行");
        log.info("目标userId：{}",userId);
        log.info("目标会话：{}",StpUtil.getSessionByLoginId((Integer.toString(userId))).get("username"));
        StpUtil.getSessionByLoginId(userId).set(key, value);
    }

    @Override
    public void update(Integer userId,Map<String, Object> updateArgs) {

        for(Map.Entry<String,Object> entry: updateArgs.entrySet()){
            StpUtil.getSessionByLoginId(userId).set(entry.getKey(),entry.getValue());
        }

    }

    //信息上传至业务redis库
    @Override
    public void uploadToServiceDB(Object mainKey, Map<String, Object> valueMap) {
        String infoId = null;
        //如果没有则新建
        if(Boolean.FALSE.equals(stringRedisTemplate.hasKey(mainKey.toString()))){
            infoId = String.valueOf(UUID.randomUUID());
            stringRedisTemplate.opsForValue().set(mainKey.toString(),infoId ,expireTime, TimeUnit.MINUTES);
            stringRedisTemplate.opsForValue().set(infoId, jsonConverter.mapToJSONString(valueMap),expireTime, TimeUnit.MINUTES);
            return;
        }


        //有则覆盖
        infoId = stringRedisTemplate.opsForValue().get(Integer.toString((Integer) mainKey));
        assert infoId != null;
        //覆盖存储
        stringRedisTemplate.opsForValue().set(mainKey.toString(),infoId ,expireTime, TimeUnit.MINUTES);
        stringRedisTemplate.opsForValue().set(infoId, jsonConverter.mapToJSONString(valueMap),expireTime, TimeUnit.MINUTES);


    }

    @Override
    public void updateToServiceDB(Object mainKey, Map<String, Object> valueMap) {
        //如果有缓存，则更新，没有则不更新
        if(Boolean.FALSE.equals(stringRedisTemplate.hasKey(mainKey.toString()))){
            return;
        }
        //先获取原来的redis数据集
        String infoId = stringRedisTemplate.opsForValue().get(Integer.toString((Integer) mainKey));

        Map<String,Object> userInfoMap = jsonConverter.JSONToMap(JSON.parseObject(stringRedisTemplate.opsForValue().get(infoId)));
        //修改键值
        userInfoMap.putAll(valueMap);
        String jsonString = jsonConverter.mapToJSONString(userInfoMap);
        //更新库
        stringRedisTemplate.opsForValue().set(infoId,jsonString,expireTime, TimeUnit.MINUTES);

    }


}
